<!-- Tabbar.vue -->
<template>
  <div class="Tabbar">
    <template v-for="(vnode, index) in patchedSlots" :key="index">
      <component :is="vnode" />
    </template>
  </div>
</template>

<script setup>
import { useSlots, computed, watch, ref, } from 'vue'
import { useRoute } from 'vue-router'
import { cloneVNode } from 'vue'

const props = defineProps({
  modelValue: { type: Number, default: 0 },
  defaultColor: { type: String, default: '#888' },
  activeColor: { type: String, default: 'red' },
  route: { type: Boolean, default: false }
})
const emit = defineEmits(['update:modelValue', 'change'])

const slots = useSlots()
const route = props.route ? useRoute() : null

// ⭐ 当启用路由模式时，内部自己维护当前 index
const innerIndex = ref(props.modelValue)

// 监听路由变化并匹配
if (props.route && route) {
  watch(
    () => route.name,
    () => {
      syncIndexWithRoute()
    },
  )
}

function syncIndexWithRoute() {
  const children = slots.default?.() || []
  const names = children.map(v => v.props?.name)
  const i = names.findIndex(n => n === route.name)
  if (i !== -1) {
    innerIndex.value = i
    emit('update:modelValue', i)
    emit('change', i)
  }
}

const patchedSlots = computed(() => {
  const children = slots.default?.() || []
  return children.map((vnode, index) => {
    const isCenter = index === 2
    const active = props.route ? innerIndex.value === index : props.modelValue === index
    return cloneVNode(vnode, {
      index,
      isActive: active,
      defaultColor: props.defaultColor,
      activeColor: props.activeColor,
      useRoute: props.route,
      onItemSelect: () => {
        emit('update:modelValue', index)
        emit('change', index)
        if (props.route) innerIndex.value = index
      },
      isCenterButton: isCenter
    })
  })
})
</script>


<style lang="scss" scoped>
.Tabbar {
  position: fixed;
  bottom: 0;
  width: 100%;
  left: 0;
  right: 0;
  display: flex;
  height: 50px;
  background-color: rgba(0, 0, 0, 0.8);
  box-sizing: content-box;
}
</style>